import common from '../../dxmodules/dxCommon.js';
import log from '../../dxmodules/dxLogger.js'
import config from '../../dxmodules/dxConfig.js'
import ota from "../../dxmodules/dxOta.js";
import driver from '../driver.js'
import utils from '../common/utils/utils.js';
import codeService from './codeService.js';
import std from '../../dxmodules/dxStd.js'
import dxMap from '../../dxmodules/dxMap.js'
import vgProService from './vgProService.js'

const netProService = {}

netProService.receiveMsg = function (data) {
    log.info('[netProService]  receiveMsg:' + JSON.stringify(data))
    if (config.get("sysInfo.owifi") == 8) {
        // TCP protocol mode
        let map = dxMap.get("NETPRO")
        let waitResponse = map.get("waitResponse")
        if (!waitResponse) {
            log.error("Please request first.")
            return
        }
        if (new Date().getTime() - waitResponse > config.get("sysInfo.touttime") * 1000) {
            log.error("Response timeout")
            map.del("waitResponse")
            return
        }
        map.del("waitResponse")
        return this.netRes({ source: 'tcp', data: common.utf8HexToStr(common.arrToHex(data)) })
    }
    if (!data.bcc) {
        log.error("Checksum error")
        return
    }
    const specProCmds = ["37", "b0", "54", "58", "56", "5A", "57"]
    if ((config.get('sysInfo.w_mode') == 2 && config.get("sysInfo.dchannel") == 64) || specProCmds.includes(data.cmd)) {
        let topic = "cmd" + data.cmd
        if (!vgProService[topic]) {
            log.error("This method has not been implemented.", topic)
            // driver.tcp.sendVg({ "cmd": data.cmd, "result": '90', "length": 0, "data": '' })
            return
        }
        vgProService[topic]({ source: 'tcp', pack: data })
    }
}

netProService.netRes = function (data) {
    log.info('[netProService]  netRes:' + JSON.stringify(data))
    // let beepFlag = config.get('sysInfo.ascan') & 1 == 1 || config.get('sysInfo.anfc') & 1 == 1
    let content = data.data.split("&&")
    let language = config.get('sysInfo.language') || 0
    if (!content[0].startsWith("code=")) {
        log.error("http/TCP protocol format error")
        // fail
        let awifi_f = config.get("sysInfo.awifi_f")
        if (awifi_f & 1 == 1) {
            std.setTimeout(() => {
                // To ensure audio-visual synchronization, the beeping should be executed slightly later; otherwise, the beeping would block the UI.
                driver.pwm.beep(config.get("sysInfo.beepd"), null, 1)
            }, 100)
        }
        if ((awifi_f >> 11) & 1 == 1) {
            if (language == 1) {
                driver.audio.play("f_eng")
            } else {
                driver.audio.play("f")
            }
        }
        if ((awifi_f >> 13) & 1 == 1) {
            driver.screen.customPopWin(language == 1 ? "fail" : "fail", 2000, false, false)
        }
        return
    }
    let code = parseInt(content[0].substring(5), 16)

    // Successful UI demonstration
    if (code == 0) {
        let wavFileName
        let resultCode
        // If text is displayed, the pop-up window will not appear.
        let flag = true
        if (content[1] == "desc=json" && content[2]) {
            let uiInfo = JSON.parse(content[2])
            let msg = uiInfo.msg
            let msgTimeout = uiInfo.msgTimeout
            let img = uiInfo.img
            let imgTimeout = uiInfo.imgTimeout
            wavFileName = uiInfo.wavFileName
            resultCode = uiInfo.resultCode
            if (img) {
                driver.screen.customShowMsgAndImg(undefined, undefined, img, imgTimeout)
                flag = false
            }
            if (msg) {
                driver.screen.customPopWin(msg, msgTimeout, false, true)
                flag = false
            }
        }
        // success
        let awifi_s = config.get("sysInfo.awifi_s")
        if (awifi_s & 1 == 1) {
            std.setTimeout(() => {
                driver.pwm.beep(config.get("sysInfo.beepd"), null, 1)
            }, 100)
        }
        if ((resultCode == "0000" || utils.isEmpty(resultCode)) && (awifi_s >> 6) & 1 == 1) {
            driver.gpio.relay(1)
        }
        // If a custom sound is provided, play the custom sound; otherwise, play the default sound.
        if (wavFileName) {
            driver.audio.play(wavFileName)
        } else if ((awifi_s >> 10) & 1 == 1) {
            if (language == 1) {
                driver.audio.play("s_eng")
            } else {
                driver.audio.play("s_eng")
            }
        }
        if ((awifi_s >> 12) & 1 == 1 && flag) {
            driver.screen.customPopWin(language == 1 ? "success" : "success", 2000, false, true)
        }
    }

    // Transmission action behavior
    if (code >= 1 && code <= 8) {
        // success
        let awifi_s = config.get("sysInfo.awifi_s")
        if (awifi_s & 1 == 1) {
            std.setTimeout(() => {
                driver.pwm.beep(config.get("sysInfo.beepd"), null, 1)
            }, 100)
        }
        if ((awifi_s >> 6) & 1 == 1) {
            driver.gpio.relay(1)
        }
        // Play audio
        driver.audio.play(code + 8)
        if ((awifi_s >> 10) & 1 == 1) {
            if (language == 1) {
                driver.audio.play("s_eng")
            } else {
                driver.audio.play("s_eng")
            }
        }
        if ((awifi_s >> 12) & 1 == 1) {
            driver.screen.customPopWin(language == 1 ? "success" : "success", 2000, false, true)
        }

    } else if (code > 8) {
        // fail
        let awifi_f = config.get("sysInfo.awifi_f")
        if (awifi_f & 1 == 1) {
            std.setTimeout(() => {
                // To ensure audio-visual synchronization, the beeping should be executed slightly later; otherwise, the beeping would block the UI.
                driver.pwm.beep(config.get("sysInfo.beepd"), null, 1)
            }, 100)
        }
        if ((awifi_f >> 11) & 1 == 1) {
            if (language == 1) {
                driver.audio.play("f_eng")
            } else {
                driver.audio.play("f_eng")
            }
        }
        if ((awifi_f >> 13) & 1 == 1 && !(code == 0x02ff && content[1].startsWith("msg="))) {
            driver.screen.customPopWin(language == 1 ? "fail" : "fail", 2000, false, false)
        }
    }

    // Get configuration information
    if (code == 0x01ff) {
        let configAll = config.getAll()
        let bleInfo = driver.uartBle.getConfig()
        if (bleInfo && typeof bleInfo == 'object') {
            configAll['sysInfo.ble_name'] = bleInfo.name
            configAll['sysInfo.ble_mac'] = bleInfo.mac
        }
        let res = "vgdevicecfginforesult=" + utils.jsonObjectToString(configAll)
        if (data.source == "http") {
            driver.http.sendVg(common.strToUtf8Hex(res))
        } else if (data.source == "tcp") {
            driver.tcp.sendVg(common.strToUtf8Hex(res))
        }
    }
    // Display text content
    if (code == 0x02ff && content[1].startsWith("msg=")) {
        let msg = content[1].substring(4).replaceAll("\"", "")
        if (content[2].startsWith("play=")) {
            let play = content[2].substring(5).replaceAll("\"", "")
            driver.audio.play(parseInt(play) + 8)
        }
        let time = 2000
        if (content[3].startsWith("msgTimeout=")) {
            time = content[3].substring(11).replaceAll("\"", "")
        }
        driver.screen.customPopWin(msg, time, false, false)

    }

    // HTTP upgrade static resources
    if (code == 0x03ff && content[1].startsWith("url=") && content[2].startsWith("md5=")) {
        let url = content[1].substring(4)
        let md5 = content[2].substring(4)
        let reboot = content[3] == 'reboot=1'
        try {
            updateBegin()
            ota.updateResource(url, md5, utils.getUrlFileSize(url) / 1024, codeService.updateResourceShell)
            updateEnd()
            if (reboot) {
                common.asyncReboot(1)
            }
        } catch (error) {
            updateFailed(error.message)
        }
    }
    // HTTP application upgrade
    if (code == 0x00ff && content[1].startsWith("url=") && content[2].startsWith("md5=")) {
        let url = content[1].substring(4)
        let md5 = content[2].substring(4)
        let reboot = content[3] == 'reboot=1'
        try {
            updateBegin()
            ota.updateHttp(url, md5)
            updateEnd()
            if (reboot) {
                common.asyncReboot(1)
            }
        } catch (error) {
            updateFailed(error.message)
        }
    }
}

function updateFailed(errorMsg) {
    if (errorMsg.includes("Download failed, please check the url")) {
        errorMsg = 'Upgrade package download failed'
    }
    if (config.get("sysInfo.language") == 1) {
        driver.screen.customPopWin("Upgrade Failed: " + (errorMsg ? errorMsg : "Upgrade package download failed"), 600000, true, "waring", false)
    } else {
        driver.screen.customPopWin("Upgrade Failed: " + (codeService.errorMsgMap[errorMsg] ? codeService.errorMsgMap[errorMsg] : "Download failed, please check the website."), 600000, true, "waring", false)
    }
}
function updateBegin() {
    if (config.get("sysInfo.language") == 1) {
        driver.screen.customPopWin("Start Upgrading", 600000, true, "waring", false)
    } else {
        driver.screen.customPopWin("Start Upgrading", 600000, true, "waring", false)
    }
}

function updateEnd() {
    if (config.get("sysInfo.language") == 1) {
        driver.screen.customPopWin("Upgrade Successfully", 2000, true, "waring", false)
    } else {
        driver.screen.customPopWin("Upgrade Successfully", 2000, true, "waring", false)
    }
}

export default netProService
